import utils from "./utils";
const defaultConfig = {
    el: "",
    jsonArr: [],
    selfIdField: "id",
    parentIdField: "parent",
    parentld: "",
    text: "text",
    type: 'list',
    viewClass: '',
    itemClass: '',
    click: (itemId, itemData, itemNode) => {}
};
export default class Tree {
    constructor(options) {
        if (!options.el || (options.el == null && options.el == "")) {
            throw "Root node cannot be empty";
            return;
        }
        this.options = Object.assign(defaultConfig, options);
        if(this.options.type === 'list') {
            this.tree = utils.convertToTreeData(
                this.options.jsonArr,
                this.options.selfIdField,
                this.options.parentIdField,
                this.options.parentld
            );
        }else if(this.options.type === 'tree') {
            this.tree = this.options.jsonArr;
        } else {
            throw Error('参数异常: type可选值为 "list"|"tree" ')
        }
    }
    render() {
        if (this.tree.length < 1) {
            return;
        }
        function getItemString(arr, options) {
            let result = "";
            arr.forEach((item, i) => {
                let child = "";
                if (item.children) {
                    child = `
                        <ul class="un-org-tree-item-childer">
                            <i class="un-org-tree--horizontal-line"></i>
                            ${getItemString(item.children, options)}    
                        </ul>`;
                }
                child = utils.trim(child);
                let childClass =
                    child.length > 0
                        ? "un-org-tree-item"
                        : "un-org-tree-item leaf";

                result += `<li class="${childClass}">
                        <span>
                            <span class="${options.itemClass}" data-id="${item[options.selfIdField]}" title="${
                                item[options.text]
                                }">${item[options.text]} 
                                <i class="un-org-tree--vertical-line top"></i>
                                ${item.children && item.children.length > 0
                                ? '<i class="un-org-tree--vertical-line bottom"></i>'
                                : ''}
                            </span>
                        </span>
                        ${child}
                   </li>`;
            });
            return result;
        }
        // 容器创建
        let wrap = document.createElement("div");
        wrap.classList.add("un-org-tree--wrapper");

        let ul = document.createElement("ul");
        ul.classList.add("un-org-tree");
        if(this.options.viewClass) {
            ul.classList.add(this.options.viewClass);
        }
        wrap.append(ul);
        let str = getItemString(this.tree, this.options);
        ul.innerHTML = str;
        this.bindEvent(ul);
        this.options.el.innerHTML = "";
        this.options.el.appendChild(wrap);
        this.setHorizontalLineWidth(this.options.el);
    }
    setHorizontalLineWidth(el) {
        // 获取需要设置宽度的线条元素
        let els = el.querySelectorAll("i.un-org-tree--horizontal-line");
        els.forEach(item => {
            // 获取父级节点
            
            // 定义最终返回宽度
            let resultWidth = 0,
                parent = item.parentNode,
                // 获取父级节点的宽度
                parentWidth = parent.offsetWidth,
                // 获取父级节点下所有的子节点
                tempChildren = parent.children,
                children = [];
            // 过滤掉非 li 节点
            for (let i = 0, len = tempChildren.length; i < len; i++) {
                if (tempChildren[i].localName === "li") {
                    children.push(tempChildren[i]);
                }
            }
            const childrenLength = children.length;
            let firstChild = 0,
                lastChild = 0;
            if (childrenLength > 1) {
                // 获取子节点中的 第一项 的宽度的一半
                    firstChild = (children[0].offsetWidth) / 2;
                // 获取子节点中的 最后一项 的宽度的一半
                lastChild = (children[childrenLength - 1].offsetWidth) / 2;
                    // 最终返回结果为 "父级节点宽度" - "子节点中的 第一项 的宽度的一半" - "子节点中的 最后一项 的宽度"的一半
                    resultWidth = parentWidth - firstChild - lastChild;
            }
            let style = `width: ${resultWidth}px; left: ${firstChild}px;`
            item.setAttribute('style', style)
        });
    }
    bindEvent(el) {
        // 事件委托
        el.addEventListener("click", e => {
            if (
                el.contains(e.target) &&
                e.target.tagName == "SPAN" &&
                e.target.dataset.id
            ) {
                let id = e.target.dataset.id;
                let data = this.options.jsonArr.filter(
                    item => item.id === e.target.dataset.id
                );
                this.options.click(id, data[0], e.target);
            }
        });
    }
}
